package Network;

import chataudio.Constant;
import controleur.AbstractChatControleur;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import model.Connection;

/**
 * La classe ThreadServerTCP gére le serveur TCP <br>
 * @author Romain Bustos
 * @author Matthieu Perrin
 * @version 1.0
 */
public class ThreadServerTCP extends Thread {
   private Socket client = null;
   private ObjectInputStream ois = null;
   private ObjectOutputStream oos = null;
   private AbstractChatControleur control;
   ServerSocket arrayServer;
   private boolean running = true;

   public ThreadServerTCP( AbstractChatControleur controleur) throws IOException {
       this.control = controleur;
       this.arrayServer = new ServerSocket(Constant.tcpPort);
       
        try {
            ois = new ObjectInputStream(client.getInputStream());
            oos = new ObjectOutputStream(client.getOutputStream());
        } catch(Exception e1) {
            try {
                client.close();
            }catch(Exception e) {
                System.out.println(e.getMessage());
            }
        }
   }
   
   public void StartConnection(){
       this.start();
   }


    @Override
   public void run() {

      try {
        // ---- DEBUT BOUCLE THREAD ----
        while (running) 
        {
            client = arrayServer.accept();
            ois = new ObjectInputStream(client.getInputStream());
            oos = new ObjectOutputStream(client.getOutputStream());
            Connection con2 = new Connection((Connection) ois.readObject(), control);
            con2.setAdresse(client.getInetAddress());
            System.out.println("\n" + con2.toString());

            //Traitement
            this.processing(con2);
            
        }
        // ---- FIN BOUCLE THREAD ----
          
         fermeture(); 
          System.out.println("FIN DE TRAITEMENT SERVER TCP");
      } 
      catch(IOException e) {
          System.out.println(e.toString());  
      }
      catch(ClassNotFoundException c){
          
      }
   }
    
    
    private void processing(Connection con2) throws UnknownHostException, IOException 
    {
        if (con2.getState() == Constant.Status.SEND) {
                con2.setState(Constant.Status.WAITING_FOR_ACCEPTATION);
                con2.setAdresse(client.getInetAddress());
                //con2.setServer();
                control.AddConnToWaitList(con2);
            } else if (con2.getState() == Constant.Status.WAITING_FOR_ACCEPTATION) {
                con2.setState(Constant.Status.WAITING_FOR_RESPONSE);
                control.notifyConnectionChanged();
            } else if (con2.getState() == Constant.Status.ACCEPTED) {
                // demarre la session audio pour la conection
                System.out.println("demarre une session audio avec: " + con2.toString());
                control.getConnection(con2.getID()).start();
                control.putConWaitToActiv(con2.getID());
                control.startChrono();
                control.removeConnToWaitList(con2);
                       
            } else if ( con2.getState() == Constant.Status.REFUSED){
                control.removeConnToWaitList(control.getWaitingConnection(con2.getID()));
                //con2.setState(Constant.Status.REFUSED);
            } else if (con2.getState() == Constant.Status.STOP) {
                // arrete la session audio pour la conection
                control.getActiveConnection(con2.getID()).stop();
                
                //control.removeConnToActiveList(con2);
                control.AddConnToWaitList(control.getActiveConnection(con2.getID()));
                
                control.removeConnToActiveList(control.getActiveConnection(con2.getID()));
                
            
            } else if (con2.getState() == Constant.Status.NETWORK) {
                // modifie le port de la connection
                control.getConnection(con2.getID()).setportRecptionUDP(con2.getportEnvoieUDP());
            }
        
        this.returnToCLient(con2);
    }
    
    private void returnToCLient(Connection con2) throws UnknownHostException, IOException
    {
        Connection output = new Connection(con2.getID(), con2.getName(), con2.getUser(), control);
        output.setState(Constant.Status.WAITING_FOR_RESPONSE);
        //output.setName(control.getCurrentUser().getNom());
        output.setUser(control.getCurrentUser().getNom());
        oos.writeObject(output);
        oos.flush();
    }
    
    private void fermeture() throws IOException
    {        
        System.out.println("arret srver tcp");
         // close connections
         ois.close();
         oos.close();
         client.close(); 
    }
    
    public void arret()
    {
        running = false;
    }
}
